import Player = egret.sys.Player;
/**
 * Created by Administrator on 2016/11/19.
 */
//数据代理
class GSDataProxy {

    static _i: GSDataProxy;

    static get i() {
        return GSDataProxy._i || (GSDataProxy._i = new GSDataProxy);
    }

    gData: GSData;

    constructor() {
        this.gData = GSData.i;
    }

    //断线重连
    S2C_RebackData(obj: any) {

        this.gData.rebackData = obj;

        game.roomid = obj.roomid;

        PublicVal.i.bao = obj.bao;
        PublicVal.i.backTing = obj.ting;

        this.gData.turnPos = obj.turn;
        this.gData.zhuangPos = obj.zhuang;
        this.gData.lastZhuangPos = obj.zhuang;
        this.gData.ting_list = obj.ting_list;

        game.roomRound = obj.max_round;
        game.roomRoundCur = obj.cur_round;
        game.roomPaidui = obj.dui_num;

        switch (obj.status) {
            case "wait_for_join":
                this.gData.rebackStatus = 1;
                break;
            case "wait_for_play":
            case "wait_for_deal":
            case "wait_for_resume":
            case "wait_for_dismiss":
            case "wait_for_wake":
                this.gData.rebackStatus = 3;
                break;
            case "wait_for_continue":
                this.gData.rebackStatus = 2;
                this.gData.roundStarted = true;
        }

        gameManager.socketManager.send(25, { type: 3 });
    }

    //解析离线数据
    parseRebackPai() {

        this.gData.turnDir = PublicVal.i.getDir(this.gData.turnPos);
        this.gData.zhuangDir = PublicVal.i.getDir(this.gData.zhuangPos);

        PublicVal.i.zhuangFlag = 1 << this.gData.zhuangDir;

        let persons = this.gData.rebackData.person;
        let lastPai = this.gData.rebackData.draw;

        for (let i: number = 0; i < persons.length; i++) {
            let person = persons[i];
            let pos = person.pos;
            let dir = PublicVal.i.getDir(pos);
            let men = person.men;
            let shou = person.shou;
            let wai = person.wai;
            let cur = person.cur;
            let unan = person.unan;

            let hu: any = person.hu;
            if (hu && hu.length) {
                let mjview: GameSceneMJLayer = GSController.i.gsView.MJViews[dir];
                for (let j: number = 0; j < hu.length; j++) {
                    mjview.pushHu(hu[j]);
                }

                if (dir == 1) {
                    game.isHu = true;

                    if (lastPai && lastPai != "no") {
                        egret.setTimeout(function () {
                            gameManager.socketManager.send(4, lastPai);
                        }, this, 2000);
                    }
                }
            }

            GSData.i.gangCurs[dir] = cur;

            if (Object.keys(men).length > 0) {//解析功能牌

                let funcPais = PublicVal.i.getFuncPais(dir);

                if (men[1]) {
                    for (let i: number = 0; i < men[1].length; i++) {
                        PublicVal.i.addFuncPai(4, dir, 1, men[1][i]);
                    }
                }
                if (men[2]) {
                    for (let i: number = 0; i < men[2].length; i++) {
                        PublicVal.i.addFuncPai(5, dir, 2, men[2][i]);
                    }
                }
                if (men[24]) {//暗杠
                    for (let i: number = 0; i < men[24].length; i++) {
                        PublicVal.i.addFuncPai(1, dir, 24, men[24][i]);
                    }
                }
                if (men[25]) {//明杠
                    for (let i: number = 0; i < men[25].length; i++) {
                        PublicVal.i.addFuncPai(2, dir, 25, men[25][i]);
                    }
                }
                if (men[22]) {//幺九杠
                    for (let i = 0; i < men[22].length; i++) {
                        let menK1 = men[22][i];
                        let num = menK1[0].number;
                        let pais = menK1.slice(-3);
                        menK1.length -= 3;
                        let ever = [1, 1, 1];
                        for (let j: number = 0; j < menK1.length; j++) {
                            ever[menK1[j].type - 1]++;
                        }
                        funcPais.push({ sort: 3, action: 22, pais: [{ pai: pais, number: num, ever: ever }] });
                    }
                }
                if (men[23]) {//旋风杠
                    let pais: any[] = [];
                    for (let i: number = 0; i < men[23].length; i++) {
                        pais = men[23][i];
                        pais.push(pais.shift());
                        PublicVal.i.addFuncPai(2, dir, 23, pais);
                    }
                }
                if (men[26]) {//中发白杠
                    let pais: any[] = [];
                    for (let i: number = 0; i < men[26].length; i++) {
                        pais = men[26][i];
                        PublicVal.i.addFuncPai(0, dir, 26, pais);
                    }
                }
            }

            if (unan == 1) {
                GameHandy.turnAngang(pos);
            }

            if (shou > 0) {//其他人的牌
                this.gData.setHandPais(dir, new Array(shou));
            }
            else {//自己的牌
                FashionTools.sortPai(shou);

                //判断长度
                if (GSConfig.allowLens(shou.length)) {
                    let zhuangpai = null;
                    if (person.draw == "no") {
                        zhuangpai = (this.gData.rebackData.step == 5 ? person.zhuangpai : null);
                    } else {
                        zhuangpai = person.draw;
                    }

                    if (zhuangpai) {
                        FashionTools.removePai(shou, zhuangpai);
                        shou.push(zhuangpai);
                        this.gData.setCatchPai(1, zhuangpai);

                    } else {
                        this.gData.setCatchPai(1, shou[shou.length - 1]);
                    }
                }

                this.gData.setHandPais(1, shou);
            }

            if (wai.length > 0) {//池牌
                wai.reverse();
                this.gData.setPoolPais(dir, wai);
            }
        }
    }


    //删除手牌
    S2C_DeletePai(pos: number, pai: any) {
        let dir = PublicVal.i.getDir(pos);
        PublicVal.i.removeHandPai(dir, pai);

        if (dir == 1) FashionTools.sortPai(PublicVal.i.getHandPais(dir));

        GSController.i.updateMJView(dir);
    }

    //更新功能菜单，吃蹦杠
    S2C_Function(obj: any) {
        //准备听的状态，忽略其他人上线刷新的功能菜单
        if (GSData.i.readyTing) return;

        //不能操作出牌
        this.gData.isShowFunc = true;
        this.gData.funcSelects = [{ index: 0, action: 0, pai: null }];


        if (obj[1]) {
            let pais = obj[1];
            let group = [];
            for (let i: number = 0; i < pais.length; i += 3) {
                group.push({ action: 1, pai: pais.slice(i, i + 3) });
            }
            this.gData.funcSelects.push({ index: 1, group: group });
        }
        if (obj[2]) {
            this.gData.funcSelects.push({ index: 2, action: 2, pai: obj[2] });
        }



        if (obj[22] || obj[23] || obj[24] || obj[25] || obj[26]) {
            let group = [];

            if (obj[24]) {//暗杠
                let pais = obj[24];
                for (let i: number = 0; i < pais.length; i += 4) {
                    group.push({action: 24, pai: pais.slice(i, i + 4)});
                }
            }

            if (obj[25]) {//明杠
                let pais = obj[25];
                for (let i: number = 0; i < pais.length; i++) {
                    group.push({action: 25, pai: pais[i]});
                }
            }

            if (obj[22]) {//幺九杠
                let pais = obj[22];
                for (let i: number = 0; i < pais.length; i += 3) {
                    group.push({action: 22, pai: pais.slice(i, i + 3)});
                }
            }

            if (obj[23]) {//旋风杠
                group.push({action: 23, pai: obj[23]});
            }

            if (obj[26]) {//中发白杠
                group.push({action: 26, pai: obj[26]});
            }
            this.gData.funcSelects.push({index: 3, group: group});
        }

        if (obj[27] || obj[28]) {
            let group = [];
            if (obj[27]) {//幺九杠 补蛋
                let pais = obj[27];
                let add: any = {};
                for (let i: number = 0; i < pais.length; i++) {
                    let flag: number = pais[i].type << 8 | pais[i].number;
                    if (!add[flag]) {
                        group.push({ action: 27, pai: pais[i] });
                        add[flag] = true;
                    }
                }
            }

            if (obj[28]) {//中发白  补蛋
                let add: any = {};
                let pais = obj[28];
                for (let i: number = 0; i < pais.length; i++) {
                    let flag: number = pais[i].type << 8 | pais[i].number;
                    if (!add[flag]) {
                        group.push({ action: 28, pai: pais[i] });
                        add[flag] = true;
                    }
                }
            }

            this.gData.funcSelects.push({ index: 4, group: group });
        }

        if (obj[4]) {//听 group 数组对象[{play,hu[]},...];
            if (this.checkHasTing()) {
                this.gData.funcSelects.push({ index: 5, action: 4, group: obj[4] });
            }
            this.gData.handCardPrompt[AngleType.tingPrompt] = obj[4];
        }

        if (obj[99]) {//胡
            //this.gData.funcSelects.push({index: 5, action: 4, pai: data[4]});
            this.gData.funcSelects.push({ index: 6, action: 99, pai: obj[99] });
            this.gData.funcSelects[0].hasAction = 99;
            if (game.isHu) {

            }
        }
        //断线重连上来的情况
        if (this.gData.rebackData) {
            this.gData.rebackViewFuncs.push([GSController.i.showFuncSelectMenu, GSController.i]);
        }
        else {
            GSController.i.showFuncSelectMenu();
        }

        FashionTools.autoPass();
    }

    //轮到哪个方向出牌
    S2C_TurnDir(pos: number, dui_num: number, gang_end: any = null) {
        GSController.i.clearDelayPushInterval();

        this.gData.turnDir = PublicVal.i.getDir(pos);
        console.log("轮到 " + this.gData.turnDir + " 抓牌");

        game.roomPaidui = dui_num;
        if (GameConfig.tipsLastCards && game.roomPaidui <= 4 && game.roomPaidui > 0) {
            EffectTextUtils.showTips("剩余最后" + game.roomPaidui + "张", 5);
        }

        if (this.gData.turnDir != 1 && PublicVal.state != StateType.shuffle) {// && this.gData.isZhuangPush) {
            //轮到他人的时候，并且庄家出完牌,进行假象牌的添加
            this.gData.pushHandPai(this.gData.turnDir, null);
            GSController.i.catchCard(this.gData.turnDir);
        }
        GSController.i.setHeadFrame(pos);
        GSController.i.setArrowDir(this.gData.turnDir);
        GSController.i.updateCenterInfo();
        GSController.i.gsView.updateRoom();
        GSController.i.gsView.resetAllChildrenTouch();
    }

    //更新自己抓牌
    S2C_OwnCatch(pai: any, dui_num: number, fen: boolean = false) {

        this.gData.setCatchPai(1, pai);
        this.gData.pushHandPai(1, pai);

        game.roomPaidui = dui_num;

        if (GameConfig.tipsLastCards && game.roomPaidui <= 4 && game.roomPaidui > 0) {
            EffectTextUtils.showTips("剩余最后" + game.roomPaidui + "张", 5);
        }

        this.gData.turnDir = (fen ? 0 : 1);

        if (fen) {
            PublicVal.state = StateType.fen;
            console.log("尾局分张");
        }

        GSController.i.catchCard(1);
        GSController.i.updateCenterInfo();
        GSController.i.setHeadFrame(PublicVal.i.getPos(1));
        FashionTools.autoPush();
        GameSound.play("sound_card_hover");
    }

    //上听后,更换左上角为暗宝显示,存当前宝牌
    S2C_LookBao(obj:any){
        PublicVal.i.bao = obj.bao;
        GSController.i.updateBaoView();
    }

    S2C_Bao(obj: any) {
        game.roomPaidui = obj.dui_num;
        PublicVal.i.bao = obj.bao;
        GSController.i.playBao(obj.old_bao);
    }

    //更新结果 cur是当前分数
    S2C_FuncResult(data: any) {
        let action = data.action;
        let pai = data.pai;
        let pos = data.turn;
        let cur = data.cur;
        let dir = PublicVal.i.getDir(pos);
        let unan = data.unan;

        this.gData.isShowFunc = false;

        let poolPai: any = null;

        switch (action) {
            case 1://吃
                GameOthers.soundPlay(SoundType.chi, pos);
                PublicVal.i.addFuncPai(5, dir, action, pai);
                if (dir == 1) {
                    //删除手牌数据
                    this.gData.removeOwnHandPais([pai[0], pai[2]]);
                } else {
                    //删除手上两张牌
                    this.gData.removeOtherHandPai(dir, 2);
                }
                poolPai = pai[1];
                break;
            case 2://碰
                GameOthers.soundPlay(SoundType.peng, pos);
                PublicVal.i.addFuncPai(4, dir, action, pai);
                if (dir == 1) {
                    //删除手牌数据
                    this.gData.removeOwnHandPais([pai[0], pai[2]]);
                } else {
                    //删除手上两张牌
                    this.gData.removeOtherHandPai(dir, 2);
                }
                poolPai = pai[1];
                break;
            case 4://听牌
                GameOthers.soundPlay(SoundType.ting, pos);
                game.roomTing[dir] = true;
                game.isTinging = true;

                var head: HeadIcon = GSController.i.gsView.getHeadView(dir);
                head.isTing = true;
                break;
            case 24://暗杠
                GameOthers.soundPlay(SoundType.gang_an, pos);
                PublicVal.i.addFuncPai(1, dir, action, pai);
                //删除手牌数据 3
                if (dir == 1) {
                    //删除手牌数据 4
                    this.gData.removeOwnHandPais([pai[0], pai[1], pai[2], pai[3]]);
                } else {
                    this.gData.removeOtherHandPai(dir, 4);
                }

                gameManager.i.dispatchEvent(EffectEvent.Xiayu, dir);//下雨特效
                break;
            case 25://明杠分(两种 1.3张手牌杠池牌 2.已经碰牌再明杠)
                GameOthers.soundPlay(SoundType.gang_ming, pos);
                PublicVal.i.addFuncPai(2, dir, action, pai);

                let tmpPai = pai[0];
                //有碰就删除掉
                let removeLen = PublicVal.i.removePengFunc(dir, tmpPai) ? 1 : 3;

                if (dir == 1) {
                    if (removeLen == 1) {
                        this.gData.removeOwnHandPais([tmpPai]);
                    }
                    else {
                        this.gData.removeOwnHandPais([tmpPai, tmpPai, tmpPai]);
                    }
                } else {
                    this.gData.removeOtherHandPai(dir, removeLen);
                }
                if (removeLen == 3) poolPai = tmpPai;

                gameManager.i.dispatchEvent(EffectEvent.Guafeng, dir);//刮风特效
                break;
            case 22://幺九杠
            // GameSound.play((pai[0].number == 1 ? "yaogang_" : "jiugang_") + this.gData.getSexByPos(pos));
            // PublicVal.i.addFuncPai(3, dir, action, pai, pai[0].number, true);
            // if (dir == 1) {
            //     //删除手牌数据 3
            //     this.gData.removeOwnHandPais([pai[0], pai[1], pai[2]]);
            // } else {
            //     this.gData.removeOtherHandPai(dir, 3);
            //
            // GameSound.play("sound_down");
            //              break;
            case 23://旋风杠
                GameOthers.soundPlay(SoundType.gang_feng, pos);

                pai.push(pai.shift());

                PublicVal.i.addFuncPai(2, dir, action, pai);

                if (dir == 1) {
                    this.gData.removeOwnHandPais(pai);
                }
                else {
                    this.gData.removeOtherHandPai(dir, 4);
                }
                break;
            case 26://中发白杠
                GameOthers.soundPlay(SoundType.gang_jian, pos);

                PublicVal.i.addFuncPai(0, dir, action, pai, 0, true);
                if (dir == 1) {
                    this.gData.removeOwnHandPais(pai);
                } else {
                    this.gData.removeOtherHandPai(dir, 3);
                }
                break;
            case 27://幺九杠 补蛋
                // GameSound.play("bugang_" + this.gData.getSexByPos(pos));
                // pai.length -= 3;
                // let everPai = PublicVal.i.getPai(dir, 22, pai[0].number);
                // let everSrc = [1, 1, 1];
                // for (let i: number = 0; i < pai.length; i++) {
                //     everSrc[pai[i].type - 1]++;
                //
                // }
                // everPai.ever = everSrc;
                // if (dir == 1) {
                //     //删除手牌数据 3
                //     this.gData.removeOwnHandPais([pai[0]]);
                // } else {
                //     this.gData.removeOtherHandPai(dir, 1);
                // }
                // GameSound.play("sound_down");
                break;
            case 28://中发白  补蛋
                // GameSound.play("bugang_" + this.gData.getSexByPos(pos));
                // pai.length -= 3;
                // let everPai = PublicVal.i.getPai(dir, 26);
                // let everSrc = [1, 1, 1];
                // for (let i: number = 0; i < pai.length; i++) {
                //     everSrc[pai[i].number - 1]++;
                // }
                // everPai.ever = everSrc;
                // if (dir == 1) {
                //     //删除手牌数据 3
                //     this.gData.removeOwnHandPais([pai[0]]);
                // } else {
                //     this.gData.removeOtherHandPai(dir, 1);
                // }
                // GameSound.play("sound_down");
                break;
            case 99://胡牌
                let mjview: GameSceneMJLayer = GSController.i.gsView.MJViews[dir];
                mjview.pushHu(pai);
                if (GameConfig.gameType == GameType.sichuan) {
                    this.seletTingCard(pai, true);
                }
                let hu_types: any[] = data.ex_hu_type;
                if (hu_types && hu_types.length) {
                    for (let i: number = 0; i < hu_types.length; i++) {
                        let val: any = hu_types[i];
                        if (val == 19) {//杠上开花
                            GameOthers.soundPlay(SoundType.gangKai, data.turn);
                        }
                        else if (val[0] == 41) {//呼叫转移
                            GameOthers.soundPlay(SoundType.hujiaozhuanyi, data.turn, PublicVal.i.getDir(val[1]));
                        }
                        else if (val[0] == 40) {//一炮多响
                            let posArr: any = val[1];
                            let dirArr: any = [];
                            for (let j: number = 0; j < posArr.length; j++) {
                                dirArr.push(PublicVal.i.getDir(posArr[j]));
                                if (dir != PublicVal.i.getDir(posArr[j])) {
                                    mjview = GSController.i.gsView.MJViews[PublicVal.i.getDir(posArr[j])];
                                    mjview.pushHu(pai);
                                }
                                if (PublicVal.i.getDir(posArr[j]) == 1) {
                                    game.isHu = true;
                                }
                            }

                            GameOthers.soundPlay(SoundType.yipaoduoxiang, posArr[i], dirArr);
                        }
                    }
                }
                else {
                    GameOthers.soundPlay(SoundType.hu, data.turn, this.gData.turnDir == dir);

                    if (this.gData.turnDir != dir) {
                        GSController.i.gsView.playFuncEffect(PublicVal.i.getDir(pai.pos), 98);
                    }
                }

                if (this.gData.turnDir != dir) {//接炮胡
                    poolPai = pai;
                }

                if (PublicVal.i.getDir(pai.pos) == dir) {
                    if (dir == 1) {
                        this.gData.removeOwnHandPais([pai]);
                    }
                    else {
                        this.gData.removeOtherHandPai(dir, 1);
                    }
                }

                if (dir == 1) {
                    game.isHu = true
                }
                break;
            default:
                console.log("未解析的功能菜单", action);
                break;
        }

        if (unan == 1) {
            GameHandy.turnAngang(pos);
        }

        this.gData.turnDir = dir;

        if (cur != null) {
            for (let k in cur) {
                this.gData.gangCurs[PublicVal.i.getDir(Number(k))] = cur[k];
            }

            GSController.i.updateGangCur(action == 24 || action == 25 || action == 99);
        }

        //删除池子牌显示
        if (poolPai && poolPai.pos > 0) {
            PublicVal.i.popPoolPai(PublicVal.i.getDir(poolPai.pos));
            GSController.i.removePoolCard(PublicVal.i.getDir(poolPai.pos));
        }

        GSController.i.setHeadFrame(pos);
        GSController.i.setArrowDir(dir);
        GSController.i.updateMJView(dir);
        // GSController.i.soundPlay(dir, action);

        GSController.i.playTimeEffect(true, dir == 1);
    }

    //S2C 更新打入池中的牌子
    S2C_PoolPai(data: any) {
        let dir = PublicVal.i.getDir(data.pos);

        this.gData.currPoolPai = data;
        this.gData.currPoolPai.dir = dir;

        GameSound.play("sound_throw");

        if (game.isTinging) {
            game.isTinging = false;
            GameSound.play("ting_" + this.gData.getSexByPos(data.pos), data.type + "_" + data.number + "_" + this.gData.getSexByPos(data.pos));
        }
        else {
            GameSound.play(data.type + "_" + data.number + "_" + this.gData.getSexByPos(data.pos));
        }

        //添加池牌数据
        PublicVal.i.pushPoolPai(dir, this.gData.currPoolPai);

        //清除手牌数据
        if (dir == 1) {
            PublicVal.i.removeHandPai(dir, this.gData.currPoolPai);
            // GSDataProxy.i.gData.removeOwnHandPais([this.gData.currPoolPai]);
        } else {
            GSDataProxy.i.gData.removeOtherHandPai(dir, 1);
        }

        if (PublicVal.state == StateType.ting || game.isHu) {
            GSController.i.clearDelayPushInterval();
        }

        console.log("出牌人的方位:", dir);
        //触发出牌显示
        GSController.i.pushPoolCard(dir, this.gData.currPoolPai);
    }

    S2C_FinalResult(result: any) {
        this.gData.result = result;
        GSController.i.clearDelayPushInterval();
        GSDataProxy.i.seletTingCard(null, false);
        GSController.i.visTingPaiBtn(false);
        if (PublicVal.state == StateType.fen) {//分张 延时
            egret.setTimeout(this.delay_Final, this, 1200);
            return;
        }

        this.delay_Final();
    }

    delay_Final() {
        const isReplay: boolean = PublicVal.state == StateType.replay;

        if (PublicVal.state == StateType.ting) {
            GSData.i.tingEndShow = true;
        }

        if (!isReplay) {
            PublicVal.state = StateType.gameover;
        }

        this.gData.roundStarted = true;

        let hupai = this.gData.result.hupai;

        //手牌排序
        for (let i: number = 0; i < this.gData.result.person.length; i++) {
            let left = this.gData.result.person[i].left;
            FashionTools.sortPai(left);
        }

        //分张排序
        let fen = this.gData.result.fen;
        if (fen) {
            let fenLeft;
            for (let i: number = 1; i <= 4; i++) {
                if (fen[i]) {
                    fenLeft = GSData.i.getResultPersonLeft(PublicVal.i.getDir(i));
                    this.formatLeft(fenLeft, fen[i]);
                }
            }
        }

        if (hupai == 0) {//流局
            this.gData.resultType = 3;
        }
        else if (hupai == 1) {
            let person: any;
            for (let i: number = 0; i < GSData.i.result.person.length; i++) {
                person = GSData.i.result.person[i];
                if (PublicVal.i.getDir(person.pos) == 1) {
                    this.gData.resultType = person.hus.length ? 1 : 2;
                }
            }
        }
        else {
            this.gData.resultType = 2;

            //是否自摸
            let selfHu: boolean = false;
            let hu_pos: number[] = typeof hupai.pos_hu == 'number' ? [hupai.pos_hu] : hupai.pos_hu;

            for (let i: number = 0; i < hu_pos.length; i++) {
                selfHu = false;
                switch (hupai.type) {
                    case 17://点炮
                        this.gData.result.dianPaoPos = hupai.pos;
                        !isReplay && GameSound.play("dianpao_" + this.gData.getSexByPos(hu_pos[i]));
                        break;
                    case 29://天胡
                        !isReplay && GameSound.play("zimo_" + this.gData.getSexByPos(hu_pos[i]));
                        selfHu = true;
                        break;
                    case 13://摸宝
                        !isReplay && GameSound.play("bao_" + this.gData.getSexByPos(hu_pos[i]));
                        selfHu = true;
                        break;
                    case 7://自摸
                        !isReplay && GameSound.play("zimo_" + this.gData.getSexByPos(hu_pos[i]));
                        selfHu = true;
                        break;
                }

                let huDir = PublicVal.i.getDir(hu_pos[i]);
                if (huDir == 1) {
                    this.gData.resultType = 1;
                }

                //胡家的剩余牌
                let hu_left: any[] = GSData.i.getResultPersonLeft(huDir);
                if (selfHu) {
                    this.formatLeft(hu_left, hupai.pai);
                } else {
                    hu_left.push(hupai.pai);
                    !isReplay && GSController.i.gsView.playFuncEffect(PublicVal.i.getDir(hupai.pos), 20000);
                }


                !isReplay && GSController.i.playEffect(huDir, 99);


            }
        }
        if (isReplay) {
            GSController.i.intoResultViewInReplay();
        } else {
            GSController.i.hupaiShow();
        }

    }

    //格式下剩余牌
    formatLeft(left, pai) {
        let leftLen: number = left.length;
        for (let k: number = 0; k < leftLen; k++) {
            if (left[k].number == pai.number && left[k].type == pai.type) {
                left.splice(k, 1);
                break;
            }
        }
        if (left.length != leftLen) { //如果长度变化，说明提出了胡牌
            left.push(pai);
        }
    }
    //中间状态 答复
    S2C_Ask(data: any) {
        GSController.i.updateHeadEffect(data.pos, HeadEffType.flash, true);

    }
    //中间状态 清除
    S2C_ClearAsk(data: any) {
        GSController.i.updateHeadEffect(data.pos, HeadEffType.flash, false);
    }

    //同步继续游戏
    S2C_ContinueGame(obj: any) {
        let dir: number = PublicVal.i.getDir(obj.pos);
        this.gData.readyFlag |= 1 << dir;
        //玩家自己的时候刷新显示
        GSController.i.visibleReadyIcon();

        if (dir == 1) {
            GSController.i.showStateView();
        }

        GameSound.play('sound_ready');
    }

    //同步房间玩家信息,判断方位
    S2C_RoomPlayers() {
        if (!this.gData.rebackData) this.gData.zhuangPos = 0;

        game.roomPlayerCur = 0;
        game.roomPlayerOffline = 0;
        this.gData.roomPlayers = [];

        let leave_uid = null;
        let player: PlayerVo;
        for (let uid in game.roomPlayers) {
            player = game.roomPlayers[uid];

            switch (player.status) {
                case "leave":
                    this.gData.roomPlayers[player.pos] = null;
                    leave_uid = uid;
                    //首轮开始
                    if (this.gData.roundStarted == false) {
                        if ((this.gData.readyFlag >> player.dir & 1) == 1) {
                            this.gData.readyFlag ^= 1 << player.dir;
                        }
                    }
                    break;
                case "offline":
                case "online":
                    this.gData.roomPlayers[player.pos] = player;
                    if (this.gData.roundStarted == false) {
                        this.gData.readyFlag |= 1 << player.dir;
                    }
                    game.roomPlayerCur++;
                    game.roomPlayerOffline += player.status == "offline" ? 1 : 0;
                    break;
            }
        }

        delete game.roomPlayers[leave_uid];

        GameOthers.showIP(this.gData.roomPlayers);
        GameOthers.showWarning(this.gData.roomPlayers);

        this.gData.roomOwnDir = PublicVal.i.getDir(1);

        PublicVal.i.roomOwnFlag = 1 << this.gData.roomOwnDir;

        if (this.gData.firstInRoom) {
            this.gData.firstInRoom = false;
            //每次进房间启动游戏主界面
            GSController.i.startView();
            GSConfig.gameConfigInit();

            if (this.gData.rebackData) {
                //至后解析
                this.parseReback();
                this.gData.rebackData = null;
            }
            else {
                game.roomReady();
            }
        }

        GSController.i.updateRoom();

        let diss: DissolutionPanel = gameManager.find('DissolutionPanel');
        if (diss && gameManager.layerManager.panelLayer.contains(diss)) diss.refresh();
    }

    parseReback() {
        const rData = this.gData.rebackData
        if (rData.circle_dai && rData.circle_dai.id !== undefined) {
            game.roomState = RoomState.CIRCLE;
        }
        switch (this.gData.rebackStatus) {
            case 1:
                PublicVal.state = StateType.ready;
                break;
            case 3:
                PublicVal.state = StateType.gamestart;
                //解析重连牌局
                this.parseRebackPai();
                this.parseRebackOther();
                GSController.i.rebackGame();
                //GSController.i.gsView.updateAllCount(this.gData);
                break;
            case 2://重连继续牌桌
                PublicVal.state = StateType.continue;
                let gContinue: any = this.gData.rebackData.continue;
                if (gContinue.length > 0) {
                    for (let i: number = 0; i < gContinue.length; i++) {
                        let pos = gContinue[i];
                        let dir = PublicVal.i.getDir(pos);
                        this.gData.readyFlag |= 1 << dir;
                    }
                }

                //判断显示 准备按钮
                if ((this.gData.readyFlag >> 1 & 1) == 0) {
                    GSController.i.scene.btn_continue.visible = true;
                }

                //断线重连继续界面
                GSController.i.startView();
                //GSController.i.visibleReadyIcon();
                break;
        }
    }
    /**断线重连其他操作 */
    parseRebackOther() {
        let rData = this.gData.rebackData;
        let persons = rData.person;
        let pos: number;

        /**流光效果 */
        pos = rData.turn;
        if (pos) {
            this.gData.rebackViewFuncs.push([
                GSController.i.updateHeadEffect,
                GSController.i,
                [pos, HeadEffType.frame, true]
            ]);
        }

        /**听牌提示 */
        let info = rData.ting_info;
        if (info && info.length > 0) {

            let list: any = {};
            let hu = [];
            list.info = info;
            info.forEach((item) => {
                hu.push(item.pai);
            });
            list.hu = hu;

            GSData.i.handTingCard = list;
            GSData.i.autoPushBtnVis = true;
        } else {
            GSData.i.autoPushBtnVis = game.isHu;
        }

        GSData.i.autoPushPai = rData.auto_flag;
    }
    //同步开局牌的信息(自己牌)
    S2C_OwnCardInfo(data: any) {
        console.log("开局,牌长度:", data.pai.length);

        game.roomReady();

        PublicVal.i.bao = data.bao;

        game.roomRound = data.max_round;
        game.roomRoundCur = data.cur_round;
        game.roomPaidui = data.dui_num;
        game.roomZhuangDir = PublicVal.i.getDir(data.zhuang);

        PublicVal.i.allPais[1].handPais = data.pai;
        PublicVal.i.allPais[2].handPais = new Array(game.roomPaiZhang);
        PublicVal.i.allPais[3].handPais = new Array(game.roomPaiZhang);
        PublicVal.i.allPais[4].handPais = new Array(game.roomPaiZhang);

        if (game.roomZhuangDir == 1) {
            PublicVal.i.allPais[1].catchPai = data.zhuangpai;
            //移除手牌里的庄牌
            FashionTools.removePai(PublicVal.i.allPais[1].handPais, data.zhuangpai);
        }
        else {
            // PublicVal.i.allPais[game.roomZhuangDir].handPais = new Array(game.roomPaiZhang + 1);
        }

        this.gData.zhuangPos = data.zhuang;

        this.gData.zhuangDir = PublicVal.i.getDir(data.zhuang);

        PublicVal.i.zhuangFlag = 1 << this.gData.zhuangDir;

        //判断连庄
        if (data.zhuang == this.gData.lastZhuangPos) {
            this.gData.isLianZhuang = true;
        } else {
            this.gData.isLianZhuang = false;
            this.gData.lastZhuangPos = data.zhuang;
        }

        //分数
        for (let key in data.cur) {
            GSData.i.gangCurs[PublicVal.i.getDir(+key)] = data.cur[+key];
        }

        PublicVal.state = StateType.gamestart;

        GSController.i.startGame();
    }

    //牌局都准备好.可以出牌
    S2C_RoundReadyAll() {
        if (PublicVal.state == StateType.shuffle) {
            this.gData.roundReady++;
            if (this.gData.roundReady == game.roomSeat) {
                GSController.i.roundPlay();
            }
        }
    }

    /**判断相同牌 */
    isSamePai(pai, _pai) {
        return pai.number == _pai.number && pai.type == _pai.type;
    }

    /**非出牌阶段听提示 */
    S2C_tingTishi(data: any) {
        const tishi: any = {};
        tishi.info = data;
        GSData.i.handTingCard = tishi;
        GSController.i.scene.hcPanel.init();
    }
    /**根据牌获取 数据 */
    getHandCardPromptByPai(pai: any) {
        let keys = Object.keys(this.gData.handCardPrompt);
        let data;
        keys.forEach((key) => {
            let item: any[] = this.gData.handCardPrompt[key];
            item.some((func, i, arr) => {
                if (this.isSamePai(func.play, pai)) {
                    data = func;
                    return true;
                }
                return false;
            });
        });
        return data;
    }

    /**听牌提示选中 可听牌后处理 */
    seletTingCard(pai: any, flag: boolean) {
        if (flag) {
            GSData.i.autoPushBtnVis = true;
            GSData.i.handTingCard = this.getHandCardPromptByPai(pai);
        } else {

            GSData.i.autoPushBtnVis = false;
            GSData.i.handTingCard = null;
        }

    }
    /**检测自动打牌状态下过滤功能菜单 */
    checkAutoClearFunc(): boolean {
        /**要过滤的 action 列表 */
        const clearConf: number[] = [1, 2];
        let flag: boolean = false;
        if (GSData.i.autoPushPai == true) {
            const funcs: any[] = GSData.i.funcSelects;
            if (funcs.length < 2) { return false };

            let clearList: number[] = [];

            clearConf.forEach((action) => {
                funcs.some((func, idx) => {
                    if (func.action == action) {
                        clearList.push(idx);
                        return true;
                    }
                    return false;
                });
            });

            if (clearList.length > 0) {

                if (funcs.length == clearList.length + 1) {
                    flag = true;
                } else {
                    clearList.forEach((v) => {
                        funcs.splice(v, 1);
                    });
                    flag = false;
                }

            } else {
                flag = false;
            }
        }

        if (flag) {
            this.autoPass();
        }

        return flag;
    }
    /**检测是否有听牌规则 */
    checkHasTing(): boolean {
        return false;
    }
    /**自动打牌的 过 */
    private autoPass() {

        this.gData.isShowFunc = false;

        gameManager.socketManager.send(15, { action: 0, pai: [] });
        GSController.i.hideFuncSelectMenu();

        let pais = PublicVal.i.getHandPais(1);
        if (pais) {
            if (GSConfig.allowLens(pais.length)) {
                let pai = GSData.i.getCatchPai(1);
                gameManager.socketManager.send(4, pai);
            }
        }
    }

    public sendCircleOpen() {
        if (!GameConfig.switch_circle) {

            EffectTextUtils.showTips("功能暂未开放,敬请期待", 5);

            return;
        }

        Circle.args_2015 = Circle.load_args_2015();

        if (Circle.args_2015 && Circle.args_2015.id) {

            Circle.args_2015.uid = game.player.uid;

            Circle.circle_send(2015, Circle.args_2015);

        } else {

            //纠错
            Circle.args_2015 = null;

            Circle.circle_send(2012, { uid: game.player.uid });

            //StackManager.open(CircleJoinDialog, "CircleJoinDialog");
        }
    }
}